﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.CodeDom.Compiler;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Linq.Expressions;
//--
using Refl;
using Refl.Dreaming;
using Refl.Numerics;
using Refl.Meta.Compiling;
using Refl.Extensions;
namespace Refl.TestApp
{

    public partial class Form1 : Form
    {
        Reverie r;
        bool requireupdate = true;
        TextWriter writer;
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            Natural n = new Natural(0);
            Natural n2 = new Natural(7);
            Natural n3 = new Natural(40);
            Natural n4 = new Natural(999);
            Natural n5 = new Natural(123456);
            writer = new TextBoxStreamWriter(txtConsole);
            // Redirect the out Console stream
            Console.SetOut(writer);
            Console.WriteLine("Host: Redirection initiated.");
            this.MaximumSize = this.Size;
            this.MinimumSize = this.Size;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (requireupdate)
            {
                r = new Reverie(txtReflective.Text, lang(comboBox1.Text));
                Inject();
                requireupdate = false;
            }
            r.Invoke();
            txtErrors.Text = "";
            if (r.HasErrors)
            {
                foreach(var error in r.Errors)
                {
                    txtErrors.AppendText("[" + error.Code + "] => " + error.Message);
                    txtErrors.SelectionStart = txtErrors.Text.Length;
                    txtErrors.ScrollToCaret();
                }
            }
        }
        Language lang(string l)
        {
            switch (l)
            {
                case "C#":
                    return Language.CSharp;
                case "JScript":
                    return Language.JScript;
                case "JavaScript":
                    return Language.JavaScript;
                case "VB":
                    return Language.VisualBasic;
                case "IL":
                    return Language.IL;
                case "C++":
                    return Language.CPlusPlus;
                case "F#":
                    return Language.FSharp;
                case "IronPython":
                    return Language.IronPython;
                case "IronRuby":
                    return Language.IronRuby;
                case "Lua":
                    return Language.Lua;
                default:
                    return Language.ReflectiveSharp;
            }
        }
        void Inject()
        {
            if (string.IsNullOrWhiteSpace(injections.Text)) { return; }
            List<String> sv = injections.Text.Split(',').ToList<string>();
            if (sv.Count % 2 != 0){sv.RemoveAt(sv.Count - 1);}
            for (int i = 0; i < sv.Count; i+=2)
            {
                string nam = sv.ElementAt(i).Trim();
                string val = sv.ElementAt(i + 1).Trim();
                double dbl = 0;
                if (double.TryParse(val, out dbl))
                {
                    r.InsertObject(nam, dbl);
                    continue;
                }
                if (val.ToLower() == "true")
                {
                    r.InsertObject(nam, true);
                    continue;
                }
                if (val.ToLower() == "false")
                {
                    r.InsertObject(nam, false);
                    continue;
                }
                r.InsertObject(nam, val);
            }
            
        }
        private void txtReflective_TextChanged(object sender, EventArgs e)
        {
            requireupdate = true;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            requireupdate = true;
        }

        private void injections_TextChanged(object sender, EventArgs e)
        {
            requireupdate = true;
        }
    }

    public class TextBoxStreamWriter : TextWriter
    {
        RichTextBox _output = null;

        public TextBoxStreamWriter(RichTextBox output)
        {
            _output = output;
        }

        public override void Write(char value)
        {
            base.Write(value);
            _output.AppendText(value.ToString()); // When character data is written, append it to the text box.
            _output.SelectionStart = _output.Text.Length;
            _output.ScrollToCaret();
        }

        public override Encoding Encoding
        {
            get { return System.Text.Encoding.UTF8; }
        }
    }
}
